package cn.fintecher.gis.web;


import cn.fintecher.gis.entity.Department;
import cn.fintecher.gis.entity.Operator;
import cn.fintecher.gis.entity.QDepartment;
import cn.fintecher.gis.entity.QOperator;
import cn.fintecher.gis.exception.BadRequestException;
import cn.fintecher.gis.model.request.DepartmentRequest;
import cn.fintecher.gis.model.response.DepartmentResponse;
import cn.fintecher.gis.model.response.OperatorResponse;
import cn.fintecher.gis.respository.DepartmentRepository;
import cn.fintecher.gis.respository.OperatorRepository;
import cn.fintecher.gis.service.LogInfoService;
import cn.fintecher.gis.utils.BeanUtils;
import cn.fintecher.gis.utils.ShortUUID;
import com.google.common.collect.Lists;
import com.querydsl.core.types.Predicate;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.querydsl.binding.QuerydslPredicate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/department")
@Api(value = "机构管理", description = "机构管理")
public class DepartmentController {

    private final Logger log = LoggerFactory.getLogger(DepartmentController.class);

    @Autowired
    private DepartmentRepository departmentRepository;

    @Autowired
    private OperatorRepository operatorRepository;

    @Autowired
    private LogInfoService logInfoService;


    @GetMapping("/queryDepartmentList")
    @ApiOperation(value = "查询机构信息", notes = "查询机构信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", dataType = "int", paramType = "query",
                    value = "页数 (0..N)"),
            @ApiImplicitParam(name = "size", dataType = "int", paramType = "query",
                    value = "每页大小."),
            @ApiImplicitParam(name = "sort", allowMultiple = true, dataType = "string", paramType = "query",
                    value = "依据什么排序: 属性名(,asc|desc). ")
    })
    public ResponseEntity<Page<Department>> queryDepartmentList(Pageable pageable, @QuerydslPredicate(root = Department.class) Predicate predicate) {
        log.info("查询机构列表信息");
        Page<Department> allList = departmentRepository.findAll(predicate, pageable);
        return new ResponseEntity<>(allList, HttpStatus.OK);
    }

    @GetMapping("/getDepartmentList")
    @ApiOperation(value = "查询机构信息", notes = "查询机构信息")
    public ResponseEntity<List<Department>> getDepartmentList(){
        List<Department> list = departmentRepository.findAll();
        return ResponseEntity.ok().body(list);
    }


    @GetMapping("getDepartAndUser")
    @ApiOperation(value = "获取机构及对应的用户信息", notes = "获取机构及对应的用户信息")
    public ResponseEntity<List<DepartmentResponse>> getDepartAndUser(){
        List<Department> list = departmentRepository.findAll();
        List<DepartmentResponse> departmentResponses = list.stream().map(department -> {
            DepartmentResponse response = new DepartmentResponse();
            BeanUtils.copyPropertiesIgnoreNull(department,response);
            Iterator<Operator> iterator = operatorRepository.findAll(QOperator.operator.department.id.eq(department.getId())).iterator();
            List<OperatorResponse> operatorResponses = Lists.newArrayList(iterator).stream().map(operator -> {
                OperatorResponse operatorResponse = new OperatorResponse();
                BeanUtils.copyPropertiesIgnoreNull(operator,operatorResponse);
                return operatorResponse;
            }).collect(Collectors.toList());
            response.setOperatorResponses(operatorResponses);
            return response;
        }).collect(Collectors.toList());
        return ResponseEntity.ok().body(departmentResponses);
    }

    @PostMapping("/saveDepartment")
    @ApiOperation(value = "机构信息的维护", notes = "机构信息的维护")
    public ResponseEntity<List<Department>> saveDepartment(@Validated @RequestBody DepartmentRequest request) {
        Department department = new Department();
        BeanUtils.copyPropertiesIgnoreNull(request, department);
        Department depart = departmentRepository.findById(request.getId()).orElseThrow(() -> new BadRequestException("", "找不到当前机构信息"));
        if (StringUtils.isNotBlank(request.getId())) {
            if(StringUtils.isNotBlank(request.getParentId())){
                Department parent = departmentRepository.findById(request.getParentId()).orElseThrow(() -> new BadRequestException("", "找不到对应的父机构信息"));
                if(StringUtils.isNotBlank(request.getId())){
                    if(!depart.getParentId().equals(request.getParentId())){
                        department.setDepartmentCode(parent.getDepartmentCode().concat("_").concat(ShortUUID.generateShortUuid()));
                    }else{
                        department.setDepartmentCode(depart.getDepartmentCode());
                    }
                }
            }else {
                department.setDepartmentCode(depart.getDepartmentCode());
            }
        } else {
            department.setDepartmentCode(ShortUUID.generateShortUuid());
        }
        departmentRepository.save(department);
        List<Department> list = departmentRepository.findAll();
        return ResponseEntity.ok()
                .body(list);
    }

    @DeleteMapping("/deleteDepartmentById/{id}")
    @ApiOperation(value = "通过id删除机构信息", notes = "通过id删除机构信息")
    public ResponseEntity<List<Department>> deleteDepartmentById(@PathVariable String id) {
        Iterator<Operator> operatorIterator = operatorRepository.findAll(QOperator.operator.department.id.eq(id)).iterator();
        if(operatorIterator.hasNext()){
            throw new BadRequestException("department","department.have.bound.users");
        }
        Iterator<Department> iterator = departmentRepository.findAll(QDepartment.department.parentId.eq(id)).iterator();
        if (iterator.hasNext()) {
            throw new BadRequestException("department", "existence.sub-mechanism");
        }
        Optional<Department> optional = departmentRepository.findById(id);
        if (optional.isPresent()) {
            Department department = optional.get();
            logInfoService.addLog("DepartmentController", "deleteDepartmentById",
                    "id=" + id, "删除的机构名称是:" + department.getDepartmentName());
            departmentRepository.delete(department);
        }
        List<Department> list = departmentRepository.findAll();
        return ResponseEntity.ok().body(list);
    }

}
